﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace TextToSpeechEngine
{
    public class PhonemeDatabase
    {
        #region Fields
        private string name;
        private List<Phoneme> phonemeList;
        #endregion

        #region Constructors
        public PhonemeDatabase()
        {
            phonemeList = new List<Phoneme>();
            foreach (int i in Enum.GetValues(typeof(PhonemeID)))
            {
                Phoneme ph = new Phoneme();
                ph.ID = i;
                phonemeList.Add(ph);
            }
        }
        #endregion

        #region Public methods
        public override string ToString()
        {
            string s = "";
            foreach (Phoneme ph in phonemeList)
            {
                s += ph.ToString();
            }
            return s;
        }

        public void ShowInTreeView(TreeView tr)
        {
            tr.Nodes.Clear();
            tr.Nodes.Add("Phoneme database");
            foreach (Phoneme ph in phonemeList)
            {
                string s = Enum.GetName(typeof(PhonemeID), ph.ID);
                TreeNode node = new TreeNode(s);
                node.Name = s;
                tr.Nodes[0].Nodes.Add(node);
                for (int ii = 0; ii < ph.SoundDescriptionList.Count; ii++)
                {
                    TreeNode phonemeVersionNode = new TreeNode(ph.SoundDescriptionList[ii]);
                    phonemeVersionNode.Tag = ph.SoundList[ii]; // Sets a reference to the actual sound (for easy playback).
                    tr.Nodes[0].Nodes[node.Name].Nodes.Add(phonemeVersionNode);
                }

                /*
                foreach (string str in ph.SoundDescriptionList)
                {
                  tr.Nodes[0].Nodes[node.Name].Nodes.Add(str);
                }
                 */
        
            }
            tr.ExpandAll();
        }

        public void SaveToFile(string FileName)
        {
            FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write("PhonemeDataBase");
            foreach (int iD in Enum.GetValues(typeof(PhonemeID)))
            {
                int phonemeID = phonemeList[iD].ID; // Not really needed. Also, could use "iD" directly..
                bw.Write(phonemeID);
                int numberOfVersions = phonemeList[iD].SoundDescriptionList.Count;
                bw.Write(numberOfVersions);
                for (int ii = 0; ii < numberOfVersions; ii++)
                {
                    bw.Write(phonemeList[iD].SoundList[ii].Name);
                    bw.Write(phonemeList[iD].SoundDescriptionList[ii]);
                    int soundSize = phonemeList[iD].SoundList[ii].SoundData.Length;
                    bw.Write(soundSize);
                    bw.Write(phonemeList[iD].SoundList[ii].SoundData);
                }
            }
            bw.Close();
            fs.Close();
        }

        public void LoadFromFile(string FileName)
        {
            FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);
            name = br.ReadString();
            foreach (int iD in Enum.GetValues(typeof(PhonemeID)))
            {
                phonemeList[iD].SoundDescriptionList.Clear();
                phonemeList[iD].SoundList.Clear();
                int phonemeID = br.ReadInt32();
                int numberOfVersions = br.ReadInt32();
                for (int ii = 0; ii < numberOfVersions; ii++)
                {
                    string soundName = br.ReadString();
                    string description = br.ReadString();
                    phonemeList[iD].SoundDescriptionList.Add(description);
                    int soundSize = br.ReadInt32();
                    WAVSound w = new WAVSound();
                    w.Name = soundName;
                    byte[] soundData = new byte[soundSize];
                    for (int jj = 0; jj < soundSize; jj++)
                    {
                        soundData[jj] = br.ReadByte();
                    }
                    w.SoundData = soundData;
                    w.ExtractInformation();
                    phonemeList[iD].SoundList.Add(w);
                }
            }
            br.Close();
            fs.Close();
        }
        #endregion

        #region Properties
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public List<Phoneme> PhonemeList
        {
            get { return phonemeList; }
            set { phonemeList = value; }
        }
        #endregion

    }
}
